﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace FanaticRock.AudioManage.Helpers
{
    ///<summary>网易云的一些相关内容的操作工具类，比如用来解析曲子的加密后的结果。</summary>
    public static class Music163Helper
    {
        // https://www.morfans.cn/archives/2793
        private const string _decodeKey = @"#14ljk_!\]&0U<'(";
        private static Lazy<byte[]> _lazyDecodeKeyBytes = new Lazy<byte[]>(CreateDecodeKeyBytes);
        private static byte[] DecodeKeyBytes => _lazyDecodeKeyBytes.Value;
        private static byte[] CreateDecodeKeyBytes()
        {
            return Encoding.UTF8.GetBytes(_decodeKey);
        }

        // 163 key(Don't modify):L64FU3W4YxX3ZFTmbZ+8/Sm+VDuKL1N9WbXrMSwj2roX3nFerjLZ29+ygThEbpG/oFLahRh55XqJqIJQ4AiBlcSOODs9zpp5vYAcrAFFAxq7wIzRvxO7ncsfPktQ9yWWsYtsZ8gOa2nKCFyM/gjKsqW30C5x1NFWCsDeB+ZoO80RpZqApI71m+FWWd3M4zVap69KHy55z7xs1Q7JiiRT9UyMc1qJRGh0IVz74bf8h7vnItDqauc+yU0y2rro1uJ+PiCImrO0xS74kcZY9UQ4Ifu9RK3E+q0xbYQZo4MLizOneYoNGgbTiQNqayVsd7QypgdXAOYevvcInaeRxqPRJcbpzJ5P9ZVOc1+wkW0MHq/OX01ZrNxvLChL47JZ2Mb0qiOMB0K5acx2UpLsjmjmsNYIRlIzhy7JT0kEhl2tUsvLHrixsvhna932G0NtklXAhOoKa5ks4fn+RkPhWqyDmpzrE8YKAtoW2qiCEt3u64A8BVjBz6SyGUK7FenH+ssnfjz0F3fD9O03Ta1bGb2qpw==
        public static string DecodeDescription(string description)
        {
            // 以第一个冒号后的内容开始。
            var colonIndex = description.IndexOf(':');

            if (colonIndex == -1)
            {
                return EncodeDescriptionCore(description);
            }
            else
            {
                var trimedDescription = description.Substring(colonIndex + 1);
                return EncodeDescriptionCore(trimedDescription);
            }
        }

        private static string EncodeDescriptionCore(string description)
        {
            var encyptedBytes = Convert.FromBase64String(description);
            var bKey = DecodeKeyBytes;

            using var mStream = new MemoryStream(encyptedBytes);
            using var aes = Aes.Create();
            aes.Mode = CipherMode.ECB;
            aes.Key = bKey;
            aes.Padding = PaddingMode.PKCS7;
            using var cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
            try
            {
                var tmp = new byte[encyptedBytes.Length + bKey.Length];
                var len = cryptoStream.Read(tmp, 0, encyptedBytes.Length + bKey.Length);
                var ret = new byte[len];
                Array.Copy(tmp, 0, ret, 0, len);
                return Encoding.UTF8.GetString(ret);
            }
            catch
            {
                return string.Empty;
            }
        }
    }
}
